package com.tj.collection.controller.lending;

import com.alibaba.fastjson.JSON;
import com.fqgj.common.api.Page;
import com.fqgj.common.api.annotations.ParamsValidate;
import com.fqgj.common.utils.CollectionUtils;
import com.fqgj.common.utils.StringUtils;
import com.fqgj.exception.common.ApplicationException;
import com.fqgj.log.factory.LogFactory;
import com.fqgj.log.interfaces.Log;
import com.jsoniter.output.JsonStream;
import com.tj.collection.bean.ApiResponse;
import com.tj.collection.bean.ModuleResponse;
import com.tj.collection.common.RequestLocalInfo;
import com.tj.collection.controller.admin.AdminController;
import com.tj.collection.controller.admin.request.AddAdminVo;
import com.tj.collection.controller.lending.request.ClAgentQueryRequest;
import com.tj.collection.controller.lending.request.ClAgentSaveRequest;
import com.tj.collection.controller.lending.response.*;
import com.tj.collection.db.admin.dao.AuthAdminRoleDAO;
import com.tj.collection.db.admin.entity.AuthAdminRoleEntity;
import com.tj.collection.db.dao.ClAgentsDao;
import com.tj.collection.db.dao.ClStageDao;
import com.tj.collection.db.domain.Admin;
import com.tj.collection.db.domain.Role;
import com.tj.collection.db.entity.ClAgentsEntity;
import com.tj.collection.db.entity.ClStageEntity;
import com.tj.collection.db.enums.RoleKeyEnum;
import com.tj.collection.db.service.AdminRoleService;
import com.tj.collection.db.service.AdminService;
import com.tj.collection.enums.ClAgentStatusEnums;
import com.tj.collection.enums.UserLanguageEnum;
import com.tj.collection.service.AgentManageService;
import com.tj.collection.service.AllocationService;
import com.tj.collection.service.dto.ClAgentsVo;
import com.tj.collection.service.dto.CommonParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;
import java.util.stream.Collectors;

/**
 * Created with IntelliJ IDEA.
 * User: pavan
 * Date: 2019/9/6
 * Time: 下午2:40
 */
@RestController
@RequestMapping("/collection/v2")
public class ClAgentController {

    public static final Log LOGGER = LogFactory.getLog(ClAgentController.class);

    @Autowired
    private AdminRoleService adminRoleService;
    @Autowired
    private AdminService adminService;
    @Autowired
    private AgentManageService agentManageService;
    @Autowired
    private ClStageDao clStageDao;

    @Autowired
    private ClAgentsDao agentsDao;

    @Autowired
    private AllocationService allocationService;

    @Autowired
    private AdminController adminController;

    @Autowired
    private AuthAdminRoleDAO authAdminRoleDAO;

    /**
     * 查询催后状催收人列表
     *
     * @return
     */
    @RequestMapping("/agent/common/list")
    public ModuleResponse<CollectionAgentCommonResponse> getCollectionAdminList() {
        String merchantCode = RequestLocalInfo.getCurrentAdmin().getMerchantCode();
        List<RoleKeyEnum> roleKeyEnumList = new ArrayList<>();
        roleKeyEnumList.add(RoleKeyEnum.COLLECT_STAFF);
        List<Long> roleIdList = adminRoleService.getRoleIdByRoleKeyList(roleKeyEnumList, RequestLocalInfo.getCurrentAdmin().getMerchantCode());
        if (CollectionUtils.isEmpty(roleIdList)) {
            throw new ApplicationException("Missing role!");
        }
        List<CommonParam> agentList = new ArrayList<>();
        List<Long> allCollection = adminRoleService.getAdminIdListByRoleIdList(roleIdList);
        if (CollectionUtils.isNotEmpty(allCollection)) {
            //获取当前系统所有的催收人员
            List<Admin> adminList = adminService.getAdminListByIdList(allCollection, merchantCode);
            for (Admin admin : adminList) {
                CommonParam auditor = new CommonParam();
                auditor.setValue(admin.getId() + "");
                auditor.setName(admin.getName());
                agentList.add(auditor);
            }
        }

        List<ClStageEntity> clStageEntityList = clStageDao.getStagesByMerchantCode(merchantCode);
        List<CommonParam> bucketItemList = clStageEntityList.stream().map(item -> {
            CommonParam tmp = new CommonParam();
            tmp.setValue(item.getStageCode());
            tmp.setName(item.getStageName());
            return tmp;
        }).collect(Collectors.toList());

        List<String> bucketList = clStageEntityList.stream().map(ClStageEntity::getStageName).collect(Collectors.toList());
        List<String> userLanguageList = Arrays.stream(UserLanguageEnum.values()).map(UserLanguageEnum::getDesc).collect(Collectors.toList());
        return new ModuleResponse(new CollectionAgentCommonResponse(agentList, bucketItemList, bucketList, userLanguageList));
    }

    /**
     * 催收员列表
     *
     * @param page
     * @return
     */
    @ParamsValidate
    @RequestMapping("/agent/list")
    public ModuleResponse<CollectionAgentResponse> collectionAgentList(@RequestBody ClAgentQueryRequest request, Page page) {

        LOGGER.info("== 查询agent list ==,request:{}", JsonStream.serialize(request));

        String merchantCode = RequestLocalInfo.getCurrentAdmin().getMerchantCode();
        List<ClAgentsVo> clAgentsVoList = agentManageService.getAgentList(merchantCode, request.getStageCode(), page);
        List<Integer> adminIds = clAgentsVoList.parallelStream().map(ClAgentsVo::getAdminId).collect(Collectors.toList());

        List<Long> adminIdsLong = new ArrayList<>();
        adminIds.forEach(a -> {
            adminIdsLong.add(Long.valueOf(a));
        });
        List<Admin> adminListByIdList = adminService.getAdminListByIdList(adminIdsLong);
        Map<Integer, Admin> adminIdAndMobileMap = new HashMap<>();
        adminListByIdList.forEach(a -> {
            adminIdAndMobileMap.put(a.getId().intValue(), a);
        });

        return new ModuleResponse(new CollectionAgentResponse(clAgentsVoList, adminIdAndMobileMap), page);
    }  @ParamsValidate

    @RequestMapping("/agent/list/v2")
    public ModuleResponse<CollectionAgentResponse> collectionAgentListV2(@RequestBody ClAgentQueryRequest request, Page page) {

        LOGGER.info("== 查询agent list ==,request:{}", JsonStream.serialize(request));

        String merchantCode = RequestLocalInfo.getCurrentAdmin().getMerchantCode();
        List<ClAgentsVo> clAgentsVoList = agentManageService.getAgentList(merchantCode, request.getStageCode(), page);
        List<Integer> adminIds = clAgentsVoList.parallelStream().map(ClAgentsVo::getAdminId).collect(Collectors.toList());

        List<Long> adminIdsLong = new ArrayList<>();
        adminIds.forEach(a -> {
            adminIdsLong.add(Long.valueOf(a));
        });
        List<Admin> adminListByIdList = adminService.getAdminListByIdList(adminIdsLong);
        Map<Integer, Admin> adminIdAndMobileMap = new HashMap<>();
        adminListByIdList.forEach(a -> {
            adminIdAndMobileMap.put(a.getId().intValue(), a);
        });

        return new ModuleResponse(new CollectionAgentResponseV2(clAgentsVoList, adminIdAndMobileMap), page);
    }

    /**
     * 查询催收人列表
     *
     * @return
     */
    @RequestMapping("/agent/query")
    public ApiResponse<ClAdminResponse> collectionAdminList() {
        if (!this.hasAllCollectPermission()) {
            return new ApiResponse<>(new ClAdminResponse(new ArrayList<>()));
        }
        String merchantCode = RequestLocalInfo.getCurrentAdmin().getMerchantCode();
        List<ClAgentsVo> clAgentsVoList = agentManageService.getAgentList(merchantCode, null, new Page(1000));
        return new ApiResponse<>(new ClAdminResponse(clAgentsVoList));
    }

    /**
     * 判断是否是催收主管或者更高级的权限（用来控制展示员工下拉列表）
     *
     * @return
     */
    private boolean hasAllCollectPermission() {
        List<Role> roleList = adminRoleService.getRolesByAdminId(RequestLocalInfo.getCurrentAdmin().getId());
        List<RoleKeyEnum> roleKeyEnumList = RoleKeyEnum.getCollectionAllPermissionEnum();
        for (RoleKeyEnum roleKeyEnum : roleKeyEnumList) {
            for (Role role : roleList) {
                if (roleKeyEnum.getType().equals(role.getRoleKey())) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 催收员信息保存
     *
     * @return
     */
    @ParamsValidate
    @RequestMapping("/agent/save")
    public ModuleResponse collectionAgentSave(@RequestBody ClAgentSaveRequest clAgentSaveRequest) {
        Admin admin = RequestLocalInfo.getCurrentAdmin();
        String merchantCode = RequestLocalInfo.getCurrentAdmin().getMerchantCode();
        LOGGER.info("催收员信息保存,adminId:{},clAgentSaveRequest:{}", admin.getId(), JSON.toJSONString(clAgentSaveRequest));
        if (StringUtils.isEmpty(clAgentSaveRequest.getPassword()) || StringUtils.isEmpty(clAgentSaveRequest.getName()) || StringUtils.isEmpty(clAgentSaveRequest.getAccount())) {
            return new ModuleResponse<>("invalid params");
        }

        Long newAdminId = null;
        if (clAgentSaveRequest.getAdminId() == null) {
            Page page = new Page();
            page.setPageSize(1000);

            Long collectionStuffRoleId = null;
            List<Role> roleList = adminRoleService.searchRoleList(null, page, RequestLocalInfo.getCurrentAdmin().getMerchantCode());
            for (Role r : roleList) {
                if (RoleKeyEnum.COLLECT_STAFF.getType().equals(r.getRoleKey())) {
                    collectionStuffRoleId = r.getRoleId();
                }
            }
            if (collectionStuffRoleId == null) {
                throw new ApplicationException("Add Agent Failed!");
            }

            List<Long> roleIds = new ArrayList<>();
            roleIds.add(collectionStuffRoleId);

            Admin oneAdminByAccount = adminService.getOneAdminByAccount(clAgentSaveRequest.getAccount());
            if (oneAdminByAccount != null && !oneAdminByAccount.getMerchantCode().equals(merchantCode)) {
                LOGGER.error("请保持手机号唯一性,merchantCode:{},clAgentSaveRequest:{}", merchantCode, JSON.toJSONString(clAgentSaveRequest));
                throw new ApplicationException("Please keep the mobile numbers of multiple merchants unique");
            }

            if (oneAdminByAccount != null) {
                LOGGER.info("账号已存在不再新生成,adminId:{} ", oneAdminByAccount.getId());
                //没有催收专员的角色 则自动添加
                if (!authAdminRoleDAO.checkAdminRole(oneAdminByAccount.getId().longValue(), roleIds)) {
                    AuthAdminRoleEntity authAdminRoleEntity = new AuthAdminRoleEntity();
                    authAdminRoleEntity.setAdminId(oneAdminByAccount.getId());
                    authAdminRoleEntity.setRoleId(collectionStuffRoleId);
                    authAdminRoleDAO.save(authAdminRoleEntity);
                    LOGGER.info("自动添加角色,adminId:{},roleId:{}", oneAdminByAccount.getId(), collectionStuffRoleId);
                }
            } else {
                //创建一个admin
                AddAdminVo addAdminVo = new AddAdminVo()
                        .setFullName(clAgentSaveRequest.getName())
                        .setName(clAgentSaveRequest.getName())
                        .setAccount(clAgentSaveRequest.getAccount())
                        .setProductCode("all")
                        .setRoles(roleIds)
                        .setPassword(clAgentSaveRequest.getPassword());
                //得到新的adminId
                adminController.addAdmin(addAdminVo);
                LOGGER.info("自动新建用户,name:{},account:{}", addAdminVo.getName(), addAdminVo.getAccount());
            }
            newAdminId = adminService.getOneAdminByAccount(clAgentSaveRequest.getAccount()).getId();
        } else {
            newAdminId = Long.valueOf(clAgentSaveRequest.getAdminId());
        }

        ClStageEntity clStageEntity = clStageDao.getStageByStageName(merchantCode, clAgentSaveRequest.getBucket());
        ClAgentsVo clAgentsVo = new ClAgentsVo();
        clAgentsVo.setAdminId(newAdminId.intValue())
                .setStageCode(clStageEntity.getStageCode())
                .setUserLanguageList(clAgentSaveRequest.getUserLanguageList())
                .setMaxOrdersNum(clAgentSaveRequest.getMaxOrdersNum())
                .setMinOrdersNum(clAgentSaveRequest.getMinOrdersNum());
        agentManageService.saveAgent(clAgentsVo);
        return new ModuleResponse<>();
    }

    /**
     * 催收员状态变更
     *
     * @return
     */
    @ParamsValidate
    @RequestMapping("/agent/status/save/v2")
    public ModuleResponse collectionStatusSave(@RequestBody ClAgentSaveRequest clAgentSaveRequest) {
        String merchantCode = RequestLocalInfo.getCurrentAdmin().getMerchantCode();
        ClAgentStatusEnums statusEnums = ClAgentStatusEnums.getEnum(clAgentSaveRequest.getStatus());
        if (!ClAgentStatusEnums.NORMAL.equals(statusEnums)
                && !ClAgentStatusEnums.LEAVE.equals(statusEnums)) {
            throw new ApplicationException("Status error!");
        }
        ClStageEntity clStageEntity = clStageDao.getStageByStageName(merchantCode, clAgentSaveRequest.getBucket());
        ClAgentsVo clAgentsVo = new ClAgentsVo();
        clAgentsVo.setAdminId(clAgentSaveRequest.getAdminId())
                .setStageCode(clStageEntity.getStageCode())
                .setStatus(statusEnums.getStatus());
        agentManageService.saveAgent(clAgentsVo);
        return new ModuleResponse<>();
    }


    /**
     * 催收员状态变更
     *
     * @return
     */
    @ParamsValidate
    @RequestMapping("/agent/{agentId}/delete")
    public ModuleResponse deleteAgent(@PathVariable Integer agentId) {
        LOGGER.info("删除催收员,admin:{}", JSON.toJSONString(RequestLocalInfo.getCurrentAdmin()));
        if (agentId == null) {
            return new ModuleResponse<>("empty agent");
        }
        ClAgentsEntity byAdminId = agentsDao.getByAdminId(agentId);
        if (byAdminId == null || byAdminId.getDeleted()) {
            return new ModuleResponse<>("deleted already");
        }

        if (!byAdminId.getMerchantCode().equals(RequestLocalInfo.getCurrentAdmin().getMerchantCode())) {
            return new ModuleResponse<>("agent  not belong to this merchant");
        }

        allocationService.deleteAgent(agentId, null);
        LOGGER.info("删除agent,agentId:{},id:{}", agentId, byAdminId.getId());
        //物理删除
        agentsDao.deleteById(byAdminId.getId().intValue());

        return new ModuleResponse<>("delete success");
    }

    /**
     * 查询催收配置信息
     *
     * @return
     */
    @RequestMapping("/agent/config/get")
    public ApiResponse<ClAgentConfigResponse> getAgentConfig() {
        return new ApiResponse<>(new ClAgentConfigResponse());
    }

}
